package com.dd.edu.oss.controller;

import com.alibaba.fastjson.JSONObject;
import com.dd.edu.oss.bean.UpLoadResult;
import com.dd.edu.oss.service.OSSService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

@Slf4j
@Controller
@RequestMapping("/oss")
public class OSSController {

    @Autowired
    private OSSService ossService;

    @PostMapping("/upload")
    @ResponseBody
    public UpLoadResult upload(@RequestParam("file") MultipartFile multipartFile) {
        return this.ossService.upload(multipartFile);
    }

    @PostMapping("/download")
    public ResponseEntity<Resource> download(String objName, HttpServletRequest request) throws IOException {
        InputStream is = ossService.download(objName);
        Resource resource = new InputStreamResource(is);

        String contentType = "application/octet-stream";
        return ResponseEntity.ok()
                .contentType(MediaType.parseMediaType(contentType))
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + objName + "\"")
                .body(resource);
    }

    @PostMapping("/delete")
    @ResponseBody
    public boolean delete(String objName) {
        return this.ossService.delete(objName);
    }






    String html = "<!DOCTYPE html>\n" +
            "<html >\n" +
            "<head >\n" +
            "    <title>支付提交</title>\n" +
            "    <meta charset=\"utf-8\">\n" +
            "    <meta name=\"renderer\" content=\"webkit\">\n" +
            "    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n" +
            "    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, maximum-scale=1\">\n" +
            "</head>\n" +
            "<body>\n" +
            "\t<form id=\"myForm\" action=\"http://localhost:8999/oss/upload\"  method=\"post\" accept-charset=\"UTF-8\">\n" +
            "        <input type=\"hidden\" name=\"transsource\" value=\"test01\" />\n" +
            "        <input type=\"hidden\" name=\"transdate\" value=\"\" />\n" +
            "        <input type=\"hidden\" name=\"transtime\"  value=\"\" />\n" +
            "        <input type=\"hidden\" name=\"rdseq\" value=\"\"   />\n" +
            "        <input type=\"hidden\" name=\"paytype\" value=\"S020-财险收保费\" />\n" +
            "        <input type=\"hidden\" name=\"paymentcode\" value=\"\"  />\n" +
            "        <input type=\"hidden\" name=\"sourcenotecode\" value=\"\"  />\n" +
            "        <input type=\"hidden\" name=\"applyentity\" value=\"\"  />\n" +
            "        <input type=\"hidden\" name=\"insurer\" value=\"\"  />\n" +
            "        <input type=\"hidden\" name=\"cur\" value=\"CNY\"  />\n" +
            "        <input type=\"hidden\" name=\"ouramount\" value=\"\"  />\n" +
            "        <input type=\"hidden\" name=\"title\" value=\"\" /><!-- 产品名称 -->\n" +
            "        <input type=\"hidden\" name=\"return_url\" value=\"\"  />\n" +
            "        <input type=\"hidden\" name=\"notify_url\" value=\"\"  />\n" +
            "        <input type=\"hidden\" name=\"limitpay\" value=\"0\"  /><!-- 0 无限制； 1 不能使用信用支付； -->\n" +
            "        <input type=\"hidden\" name=\"ckvalue\" value=\"\"  />\n" +
            "        <input type=\"hidden\" name=\"reqreserved2\" value=\"\"  /><!-- 主体公司 -->\n" +
            "    </form>\n" +
            "<script>\n" +
            "\twindow.onload=function(){\n" +
            "\t\tdocument.getElementById(\"myForm\").submit();\n" +
            "\t}\n" +
            "</script>\n" +
            "</body>\n" +
            "</html>\n";

    @RequestMapping("/redirect")
    public void redirect(HttpServletResponse response) {
        ServletOutputStream outputStream = null;
        try {
            response.setContentType("text/html");
            response.setCharacterEncoding("UTF-8");
            outputStream = response.getOutputStream();
            outputStream.write(html.getBytes("UTF-8"));
            outputStream.flush();
            outputStream.close();
        } catch (Exception e){

        }finally {
            if (outputStream!=null){
                try {
                    outputStream.flush();
                    outputStream.close();
                } catch (Exception e){}
            }
        }
    }

    static final String key ="XXXXXXXXXXXXXXXX";
    /**
     * 跳转支付结果页面
     * @param status 1未支付2已支付3支付失败4 支付中 5 未知
     */
    @RequestMapping("/return_page")
    public void pay_result_page(HttpServletRequest request, String status) {
        Map<String, String[]> parameterMap = request.getParameterMap();
        Map<String, Object> paramsMap =  transferMap(parameterMap);

        String key ="XXXXXXXXXXXXXXXX";
        boolean b = CryptoUtils.verifyObject(paramsMap, key, parameterMap.get(CryptoUtils.DEL_KEY_CKVALUE).toString());
        if (b) { // 验签成功
            System.out.println("验签成功");
        } else {
            System.out.println("验签失败");
        }
    }

    /**
     * 回调
     */
    @RequestMapping("/notify")
    public String notify(HttpServletRequest request) {
        Map<String, String[]> parameterMap = request.getParameterMap();
        log.info(JSONObject.toJSONString(parameterMap));
        Map<String, Object> paramsMap = transferMap(parameterMap);


        boolean b = CryptoUtils.verifyObject(paramsMap, key, parameterMap.get(CryptoUtils.DEL_KEY_CKVALUE).toString());
        if (b) { // 验签成功
            Object transState = paramsMap.get("TransState");// 支付状态
            Object payNo = paramsMap.get("RdSeq");//支付请求流水号
            Object payMadeDate = paramsMap.get("PayMadeDate");//支付时间yyyy-MM-dd HH:mm:ss
            Object amount = paramsMap.get("amount");
            Object billCode = paramsMap.get("Abstract");// 对账码
            return "SUCCESS";
        } else {
            System.out.println("验签失败");
        }
        return null;
    }

    private Map<String, Object> transferMap(Map<String, String[]> parameterMap){
        Map<String, Object> paramsMap = new HashMap<>();
        parameterMap.forEach((key, values) -> {
            if(values!=null && values.length>1 ){
                String value = values[0];
                paramsMap.put(key, value);
            }
        });
        return paramsMap;
    }

    /**
     * 查询
     */
    public String query() {
        Map<String, Object> reqMap = new HashMap<>();
        reqMap.put("transsource","");
        reqMap.put("transcode","QryRecState");
        reqMap.put("rdseq",""); // 支付发起号

        Map<String, String> respMap = new HashMap<>();
        String rtnCode = respMap.get("rtnCode");
        String transState = respMap.get("transstate");
        String billCode = respMap.get("abstract");
        String rdseq = respMap.get("rdseq");

        return null;
    }



    public static void main(String[] args) {
        System.out.println(new Solution().isValid("[([]])"));
    }
}

class Solution {
    private static final Map<Character,Integer> map = new HashMap<>();
    static{
        map.put('(',-1);
        map.put(')',1);
        map.put('{',-2);
        map.put('}',2);
        map.put('[',-3);
        map.put(']',3);
    }
    public boolean isValid(String s) {
        LinkedList<Character> list = new LinkedList<>();
        for(int i=0;i<s.length();i++){
            char c = s.charAt(i);
            boolean isClosed = false;
            if(map.containsKey(c)){
                Integer nowVal = map.get(c);


                if (list.size() > 0) {
                    Character upKey = list.getLast();
                    Integer upVal = map.get(upKey);
                    System.out.println( upKey +" , "+ c );
                    if(nowVal > 0) {
                        if (nowVal + upVal != 0) {
                            return false;
                        } else {
                            list.removeLast();
                            isClosed=true;
                        }
                    }
                }

                if(nowVal < 0) {
                    list.add(c);
                }

                if(nowVal > 0 && list.size() <= 0 && !isClosed){
                    return false;
                }
            }
        }
        return list.size() <= 0;

    }


}


